#ifndef PAHOMQTTCLIENT_H
#define PAHOMQTTCLIENT_H

#include "ThmarMqttClient.h"
#include <MQTTClient.h> // Paho MQTT C 库
#include <pthread.h>

/** 基于 Paho MQTT C 库实现的 MQTT 客户端(C++) */
#ifdef __cplusplus
namespace smq {
// 基于 Paho MQTT C 库实现的 MQTT 客户端[线程安全]
// 参考：https://eclipse.github.io/paho.mqtt.c/MQTTClient/html/index.html
// 依赖库： eclipse-paho-mqtt-c::paho-mqtt3c-static 
class PahoMqttClient : public ThmarMqttClient {
public:
    PahoMqttClient(const MQTTClient_connectOptions& conn_opts, 
        const char *serverURI = "tcp://localhost:1883",
        const char *clientID = "ThmarMqttClient", 
        int qos = 2);
    PahoMqttClient(const char *serverURI = "tcp://localhost:1883", 
        const char *username = NULL, const char *password = NULL, 
        const char *clientID = "ThmarMqttClient", 
        int timeout = 20, int keepAliveInterval = 60, int qos = 2);
    ~PahoMqttClient();

    /** 仅用于单元测试，应用层实际调用 start() * */
    int connect() override;
    /** 仅用于单元测试，应用层实际调用 stop() */
    void disconnect() override;
    /** 仅用于单元测试，不建议在实际代码中使用 */ 
    int publish(const char* topic, const char* message) override;
    /** 仅用于单元测试，应用层实际调用 registerChannel()  */
    int subscribe(const char* channel) override;
    /** 仅用于单元测试，应用层实际调用 unregisterChannel() */
    int unsubscribe(const char* channel) override;
public:
    MQTTClient client;
    MQTTClient_connectOptions conn_opts;
    const char *serverURI;
    const char *clientID;
    int qos;
    /* 用于记录是否已经初始化 */ 
    /* 避免重复初始化导致的内存泄漏 */ 
    /* 因为 PahoMqttClient 构造函数中会调用 connect() 方法， */ 
    /* 所以这里需要一个标志位来记录是否已经初始化 */ 
    /* 初始值为INT_MAX，表示还没有初始化，大于为0表示已经初始化成功，小于0的值表示初始化失败的错误码 */ 
    int initialized;
    /* 用于保证 publish() 方法的线程安全 */
    pthread_mutex_t publish_mutex;
    /* 用于保证 subscribe()和unsubscribe() 方法的线程安全 */
    pthread_mutex_t subscribe_mutex;
};

} // namespace smq
#endif // __cplusplus

/* PahoMqttClient C接口定义 */
/* 定义PahoMqttClient客户端类型的指针类型 */
typedef thmar_mqtt_client_t paho_mqtt_client_t;

/* 创建PahoMqttClient客户端 */
/* conn_opts: MQTT连接选项， 为NULL返回NULL  */
/* serverURI: MQTT服务器地址， 默认为tcp://localhost:1883 */
/* clientID: MQTT客户端ID， 默认为ThmarMqttClient */
/* qos: MQTT消息服务质量,可选值:0,1,2 */
/* 返回值：成功返回PahoMqttClient客户端指针，失败返回NULL */
THMAR_API paho_mqtt_client_t thmar_mqtt_client_create0(const MQTTClient_connectOptions* conn_opts, 
        const char *serverURI,
        const char *clientID, 
        int qos);

/* 创建PahoMqttClient客户端 */
/* serverURI: MQTT服务器地址， 默认为tcp://localhost:1883 */
/* username: MQTT用户名，可选 */
/* password: MQTT密码，可选 */
/* clientID: MQTT客户端ID， 默认为ThmarMqttClient */
/* timeout: 连接超时时间，单位秒，默认20秒 */
/* keepAliveInterval: 心跳间隔时间，单位秒，默认60秒 */
/* qos: MQTT消息服务质量,可选值:0,1,2 */
/* 返回值：成功返回PahoMqttClient客户端指针，失败返回NULL */
THMAR_API paho_mqtt_client_t thmar_mqtt_client_create(const char *serverURI, 
        const char *username, const char *password, 
        const char *clientID, 
        int timeout, int keepAliveInterval, int qos);

/* 销毁PahoMqttClient客户端 */
/* client：PahoMqttClient客户端指针，为NULL忽略 */
THMAR_API void thmar_mqtt_client_destroy(paho_mqtt_client_t client);

/* 连接MQTT服务器 */
THMAR_API int thmar_mqtt_client_connect(paho_mqtt_client_t client);

/* 断开MQTT服务器连接 */
/* client：PahoMqttClient客户端指针，为NULL忽略 */
THMAR_API void thmar_mqtt_client_disconnect(paho_mqtt_client_t client);

/* 发布MQTT消息 */
/* 参数为NULL,返回错误码 */
THMAR_API int thmar_mqtt_client_publish(paho_mqtt_client_t client, const char *topic, const char *message);

/* 订阅MQTT消息 */
/* 参数为NULL,返回错误码 */
THMAR_API int thmar_mqtt_client_subscribe(paho_mqtt_client_t client, const char *channel);

/* 取消订阅MQTT消息 */
/* 参数为NULL,返回错误码 */
THMAR_API int thmar_mqtt_client_unsubscribe(paho_mqtt_client_t client, const char *channel);

#endif // PAHOMQTTCLIENT_H